/*
This file is part of MMM.

MMM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MMM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MMM.  If not, see <http://www.gnu.org/licenses/>.
*
* @package    MMM
* @author     Nikolaus Vahrenkamp
* @copyright  2013 High Performance Humanoid Technologies (H2T), Karlsruhe, Germany
*
*/
#ifndef __ModelReaderXML_H_
#define __ModelReaderXML_H_

#include "../MMMCore.h"
#include "../MMMImportExport.h"
#include "Model.h"


#include <Eigen/Core>
#include <string> 
#include <vector>
#include <map>
#include <boost/enable_shared_from_this.hpp>


// using forward declarations here, so that the rapidXML header does not have to be parsed when this file is included
namespace rapidxml
{
	template<class Ch>
	class xml_node;
}

namespace MMM
{

/*!
	\brief This reader parses a model file in order to generate an MMM Model.
	The model syntax is compatible with the Simox::VirtualRobot package.
*/
class MMM_IMPORT_EXPORT ModelReaderXML : public boost::enable_shared_from_this<ModelReaderXML>
{
public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW

	ModelReaderXML();

	/*! 
		Load XML data.
		@param xmlFile The file to load.
		@param name An optional name that is used to distinguish between multiple models of same type. If not set, the type string is used.
	*/

	ModelPtr loadModel(const std::string &xmlFile, const std::string& name = std::string());

	//! Create a model from XML string.
	ModelPtr createModelFromString(const std::string &xmlString, const std::string& basePath = std::string(), const std::string& name = std::string());
	
protected:

	bool processRobotTag(rapidxml::xml_node<char>* tag, ModelPtr model, const std::string &basePath = std::string());
	bool processRobotNodeTag(rapidxml::xml_node<char>* tag, ModelPtr model, const std::string &basePath = std::string());
	bool processTransformTag(rapidxml::xml_node<char>* tag, ModelNodePtr model);
	bool processSensorTag(rapidxml::xml_node<char>* tag, ModelNodePtr modelNode);
	bool processPhysicsTag(rapidxml::xml_node<char>* tag, ModelNodePtr model);
	bool processChildTag(rapidxml::xml_node<char>* tag, ModelNodePtr model);
	bool processJointTag(rapidxml::xml_node<char>* tag, ModelNodePtr model);

	bool processLimitsNode(rapidxml::xml_node<char> *limitsXMLNode, float &jointLimitLo, float &jointLimitHi);

	//method to process nested files
	bool processChildFromRobotTag(rapidxml::xml_node<char>* tag, ModelNodePtr modelNode, ModelPtr model, const std::string &basePath);

    bool processRobotNodeSetTag(rapidxml::xml_node<char>* tag, ModelPtr model, const std::string &basePath = std::string());

};

typedef boost::shared_ptr<ModelReaderXML> ModelReaderXMLPtr;

}

#endif 
